package com.zh.kotlin_mvvm.provider

import android.annotation.SuppressLint
import android.content.Context
import android.net.Uri
import android.util.Log
import androidx.core.content.contentValuesOf
import androidx.core.database.getLongOrNull
import androidx.core.database.getStringOrNull
import com.blankj.utilcode.util.AppUtils

class AdProviderUtils private constructor() {

    private val TAG = "AdProviderUtils"
    private var context: Context? = null

    //数据库相关表
    internal val table = "ads"
    internal val queryTable = table //使用当前表

    //数据库相关字段
    val DB_ID_NAME = "id"
    val DB_ADID_NAME = "adId"
    val DB_DISTYPE_NAME = "disType"
    val DB_TIME_NAME = "timestamp"

    //授权字段
    val ADS_AUTHOR = Uri.parse("content://${AppUtils.getAppPackageName()}.provider/$queryTable")

    companion object {
        val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
            AdProviderUtils()
        }
    }

    internal fun setContext(context: Context) {//初始化时必须调用
        this.context = context
    }

    internal fun insert(adId: String?, disType: Int, time: Long) {
        try {
            adId?.let {
                query(adId) { id, data ->
                    if (data == null) {//没有数据就插入
                        val values = contentValuesOf(
                            DB_ADID_NAME to adId, DB_DISTYPE_NAME to disType, DB_TIME_NAME to time
                        )
                        context?.contentResolver?.insert(ADS_AUTHOR, values).apply {
                            Log.d(TAG, "insert: ${this?.pathSegments?.get(1)}")
                        }
                    } else {//有数据就更新数据
                        if (data.adId == adId && data.timestamp != time) {
                            update(id, adId, disType, time)
                        }
                    }
                }
            }
        } catch (e: Throwable) {
            e.printStackTrace()
        }
    }

    @SuppressLint("Range")
    internal fun queryAll(callback: (List<DisLikeBean>) -> Unit = {}) {
        try {
            val list = mutableListOf<DisLikeBean>()
            context?.contentResolver?.query(ADS_AUTHOR, null, null, null, null)?.apply {
                while (moveToNext()) {
                    //val id = getInt(getColumnIndex(DB_ID_NAME))
                    val adId = getStringOrNull(getColumnIndex(DB_ADID_NAME))
                    val disType = getInt(getColumnIndex(DB_DISTYPE_NAME))
                    val timestamp = getLongOrNull(getColumnIndex(DB_TIME_NAME))
                    list.add(DisLikeBean(adId, disType, timestamp))
                }
                close()
                callback.invoke(list)
            } ?: callback.invoke(mutableListOf())
        } catch (e: Throwable) {
            e.printStackTrace()
        }
    }

    @SuppressLint("Range")
    internal fun queryAllOtherApp(packageName: String, callback: (List<DisLikeBean>) -> Unit = {}) {
        try {
            val list = mutableListOf<DisLikeBean>()
            val ADS_AUTHOR = Uri.parse("content://$packageName.provider/$queryTable")
            context?.contentResolver?.query(ADS_AUTHOR, null, null, null, null)?.apply {
                while (moveToNext()) {
                    //val id = getInt(getColumnIndex(DB_ID_NAME))
                    val adId = getStringOrNull(getColumnIndex(DB_ADID_NAME))
                    val disType = getInt(getColumnIndex(DB_DISTYPE_NAME))
                    val timestamp = getLongOrNull(getColumnIndex(DB_TIME_NAME))
                    list.add(DisLikeBean(adId, disType, timestamp))
                }
                close()
                callback.invoke(list)
            } ?: callback.invoke(mutableListOf())
        } catch (e: Throwable) {
            e.printStackTrace()
        }
    }

    @SuppressLint("Range")
    internal fun query(adId: String, callback: (Int?, DisLikeBean?) -> Unit = { id, data -> }) {
        try {
            context?.contentResolver?.query(
                ADS_AUTHOR, null, "$DB_ADID_NAME = ?", arrayOf(adId), null
            )?.apply {
                    if (moveToFirst()) {
                        val id = getInt(getColumnIndex(DB_ID_NAME))
                        val adId = getStringOrNull(getColumnIndex(DB_ADID_NAME))
                        val disType = getInt(getColumnIndex(DB_DISTYPE_NAME))
                        val timestamp = getLongOrNull(getColumnIndex(DB_TIME_NAME))
                        callback.invoke(id, DisLikeBean(adId, disType, timestamp))
                    } else {
                        callback.invoke(null, null)
                    }
                    close()
                } ?: callback.invoke(null, null)
        } catch (e: Throwable) {
            e.printStackTrace()
        }
    }

    internal fun update(bookId: Int?, adId: String, disType: Int, time: Long) {
        try {
            bookId.let {
                val values = contentValuesOf(
                    DB_ADID_NAME to adId, DB_DISTYPE_NAME to disType, DB_TIME_NAME to time
                )
                context?.contentResolver?.update(
                    ADS_AUTHOR, values, "$DB_ADID_NAME = ?", arrayOf(adId)
                )
            }
        } catch (e: Throwable) {
            e.printStackTrace()
        }
    }

    internal fun delete(adId: String) {
        try {
            query(adId) { id, _ ->
                if (id != null) {
                    context?.contentResolver?.delete(ADS_AUTHOR, "$DB_ADID_NAME = ?", arrayOf(adId))
                }
            }
        } catch (e: Throwable) {
            e.printStackTrace()
        }
    }
}